package com.devframe.web.taglib;

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTag;
import javax.servlet.jsp.tagext.Tag;

import com.devframe.sysbase.loader.SysBaseContainer;
import com.devframe.sysconfig.service.CodeService;
import com.devframe.web.loader.MyWebContextLoader;

/**
 * 
 * <pre>
 * &lt;b&gt;&lt;font color=&quot;blue&quot;&gt;RadioTag&lt;/font&gt;&lt;/b&gt;
 * </pre>
 * 
 * <pre>
 * &lt;b&gt; --复选框按钮生成--&lt;/b&gt;
 * </pre>
 * <pre>
 * 支持array\list\map
 * 支持默认值
 * </pre>
 * <pre>
 * &lt;b&gt;--样例--&lt;/b&gt;
 *   RadioTag obj = new RadioTag();
 *   obj.method();
 * </pre>
 * 
 * JDK版本：JDK1.4
 * 
 * 
 */
public class CheckboxTag extends AbstractBaseTag {
	/**
	 * 
	 */
	private static final long serialVersionUID = -6580692676810809117L;

	/**
	 * 选项列表数据，可以是list,iterator,array,map等类型，可以使用request中的名字或者通过${}获取的对象。从其他对象的属性得到的数据需要使用EL表达式获取
	 */
	private Object items = null;
    /**
     * CODE_TYPE:代码类型字典名，一般为代码表名.
     * 用于直接生成代码表选项
     */
    private String codeType = null; 

	/**
	 * 默认值，支持EL表达式；支持多值：即defaultValue可以是数组，list，或者逗号分隔的字符串
	 */
	private Object defaultValue = null; // 
    /**
     * 分隔符，用于将选中值进行分割。未指定则支持[,;|]三种分隔符
     */
	private String split=null;
	/**
	 * 用于从对象中获取值，作为option的value
	 */
	private String valueField;// 
    /**
     * 用于从对象中获取值，作为option的text
     */
	private String labelField;// 
    /**
     * input的name，
     */
	private String name;// 


    /**
     * 条件字段
     */
    private String condField;

    /**
     * 条件值，支持EL表达式
     */
    private Object condValue;
	
	
	
	private List keys =new ArrayList();
    private List values =new ArrayList();

	private Set selectValues = new HashSet();

	// ////////////////////////////////////////////
	/**
	 * 标签处理逻辑，生成option列表
	 * @return SKIP_BODY
	 */
	public int doStartTag() {
		try {
			if(id==null){
			    id=name;
			}
            if(codeType!=null){
                items=SysBaseContainer.accessCacheDataHandle().getCodeMap(codeType);
            }
			if (items == null || items.equals("")) {
				return SKIP_BODY;
			}
			Object options = items;
			if (items instanceof String) {
			    options = findAttribute((String) items);
			}
			if (options == null) {
				return SKIP_BODY;
			}

            //将选中值统一转换成Set，以便后面进行判断
            selectValues = new HashSet();
			Object selectValue = null;
			if (defaultValue != null && !"".equals(defaultValue)) {
			    if(defaultValue instanceof String){
    		        selectValue = findAttribute((String)this.defaultValue); 
                    if (selectValue == null) {
                        selectValue = ((String)defaultValue).split(split==null?"[, ;|]":split);
                    }
			    } else {
			        selectValue = defaultValue;
			    }
	            if (selectValue instanceof Iterator || selectValue instanceof Collection) {
	                Iterator it = null;
	                if (selectValue instanceof Iterator) {
	                    it = (Iterator) selectValue;
	                } else {
	                    it = ((Collection) selectValue).iterator();
	                }
	                while (it.hasNext()) {
	                    selectValues.add(it.next());
	                }
	            } else if(selectValue.getClass().isArray()){
	                int length = Array.getLength(selectValue);
	                for (int j = 0; j < length; j++) {
	                    Object entry = Array.get(selectValue, j);
	                    selectValues.add(entry);
	                }
	            }
			}
			int i = 0;
			if (options instanceof Map) {
				Map map = (Map) options;
				for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
					Map.Entry entry = (Map.Entry) it.next();
					if(!validateCond(entry)){
                        continue;
                    }
					i++;
					Object value = entry.getValue();
					Object key = entry.getKey();
					keys.add(key);
					values.add(value);
				}
			} else if (options instanceof Iterator || options instanceof Collection) {

				Iterator it = null;
				if (options instanceof Iterator) {
					it = (Iterator) options;
				} else {
					it = ((Collection) options).iterator();
				}
				while (it.hasNext()) {
					Object entry = it.next();
					if(!validateCond(entry)){
                        continue;
                    }
					addOptionByEntry(entry);
				}
			} else if (options.getClass().isArray()) {// 数组
				int length = Array.getLength(options);
				for (int j = 0; j < length; j++) {
					Object entry = Array.get(options, j);
					if(!validateCond(entry)){
                        continue;
                    }
					addOptionByEntry(entry);
				}
			}
			return BodyTag.SKIP_BODY;
		} catch (Exception e) {
			return Tag.SKIP_BODY;
		}
	}
	/**
	 * 创建选项
	 * @param selectValues selectValues
	 * @param i 序号
	 * @param value 显示值
	 * @param key 关键值
	 * @author:
	 */
	private String createOption(int i, Object value, Object key) {
	    StringBuffer op = new StringBuffer();
	    op.append("<div style=\"display:inline-block;*display:inline\"><input name=\"" + name + "\" id=\"" + id + i + "\" type=\"checkbox\" value=\"").append(key)
				.append("\"");
		if (selectValues!=null && selectValues.contains(key)) {
		    op.append(" checked");
		}
		if(this.getStyle()!=null){
		    op.append("style=\"").append(getStyle()).append("\"");
		}
		op.append(" onclick=\"" + this.getOnclick() + "\" >").append("<label for=\"" + id + i + "\">").append(value)
				.append("</label></div>");
		return op.toString();
	}

	/**
	 * 根据选中值渲染checkbox，
	 * @param selectValues selectValues
	 * @param i 序号
	 * @param entry entry
	 * @author:
	 */
	private void addOptionByEntry(Object entry) {
		Object value;
		Object key;
		if (entry instanceof Map.Entry) {
			value = ((Map.Entry) entry).getValue();
			key = ((Map.Entry) entry).getKey();
		} else {
			if (valueField == null || valueField.equals("")) {
				key = entry.toString();
			} else {
				key = getPropertyValue(valueField, entry);
			}
			if (labelField == null || labelField.equals("")) {
				value = key;
			} else {
				value = getPropertyValue(labelField, entry);
			}
		}
        keys.add(key);
        values.add(value);
	}
    /**
     * 标签结束
     * @return EVAL_PAGE
     * @exception JspException JspException
     */
	public int doEndTag() throws JspException {
		try {
			JspWriter writer = null;
			try {
				writer = this.getPreviousOut();
			} catch (Exception e1) {
				writer = pageContext.getOut();
			}
		    /**
		     * 结果生成字符串缓存
		     */
		    StringBuffer result = new StringBuffer();
		    for(int i=0;i<keys.size();i++){
		        result.append(createOption(i,values.get(i),keys.get(i)));
		    }

			try {
				writer.print(result.toString());
				result = new StringBuffer();
			} catch (Exception e) {
				e.printStackTrace();
			}
			resetTag();
			return Tag.EVAL_PAGE;
		} catch (Exception e) {
			return EVAL_PAGE;
		}
	}
	
    /**
     * validateCond
     * 
     * @param item
     *            当前对象
     * @return 是否符合条件
     * 
     */
    private boolean validateCond(Object item) {
        if(this.condField==null || "".equals(this.condField)){
            return true;
        }
        if (item != null && !item.getClass().isPrimitive()) {
            Object condFieldValue = getPropertyValue(this.condField, item);
            if (condFieldValue != null && condFieldValue.equals(condValue)) {
                return true;
            }
        }
        return false;
    }    
    

	
    /**
     * 释放，清空结果
     */
	public void release() {
	    resetTag();
        super.release();
	}
	
	public void resetTag(){
	    this.id=null;
        this.name=null;
        this.items=null;
        this.codeType=null;
        this.labelField=null;
        this.valueField=null;
        this.defaultValue=null;
        this.keys.clear();
        this.values.clear();
        this.selectValues.clear();
	}

	public Object getItems() {
		return items;
	}

	public void setItems(Object items) {
		this.items = items;
	}

	public void setItems(String items) {
		this.items = items;
	}

	public Object getDefaultValue() {
		return defaultValue;
	}

	public void setDefaultValue(Object defaultValue) {
		this.defaultValue = defaultValue;
	}

	public String getValueField() {
		return valueField;
	}

	public void setValueField(String valueField) {
		this.valueField = valueField;
	}

	public String getLabelField() {
		return labelField;
	}

	public void setLabelField(String labelField) {
		this.labelField = labelField;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}



	public String getSplit() {
		return split;
	}

	public void setSplit(String split) {
		this.split = split;
	}

    public String getCodeType() {
        return codeType;
    }

    public void setCodeType(String codeType) {
        this.codeType = codeType;
    }

}
